﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenGL;

namespace Galaxy
{

	public class EnergyProducer
	{
		public EnergyProducer(double maxpower)
		{
			this.MaxPower = maxpower;
			this.OutPutSwitch = 1;
			this.RequestedPower = 0;
			this.RequestExceeded = false;
		}
		public double MaxPower;
		public double OutPutSwitch;
		public void SetOutput(double n)
		{
			n = Math.Min(0, Math.Max(1, n));
		}
		public PT1 CurrentEnergyStream = new PT1(1, 1, 0);
		public double RequestedPower;
		public void RequestPower(double power)
		{
			RequestedPower += power;
			RequestExceeded = RequestedPower < power;
		}
		public bool RequestExceeded;
		public double AddPower()
		{
			return Math.Min(RequestedPower, MaxPower * CurrentEnergyStream.Value);
		}

		public virtual void Process(double dt)
		{
			CurrentEnergyStream.Set(Math.Max(0, Math.Min(OutPutSwitch * MaxPower, RequestedPower)));
			CurrentEnergyStream.Process(dt);
		}
	}
	public class ConversionEnergyProducer : EnergyProducer
	{
		public ConversionEnergyProducer(double maxpower)
			: base(maxpower)
		{
		}
		public String Material;
		public double Amount, Energy, BurnRate;
		public PT1 Efficiency;
		double MinimumWeight;
		public double MaterialEfficiency
		{
			get
			{
				return Math.Min(1, Amount / MinimumWeight);
			}
		}
		public void SetMaterial(string name, double amount, double energy, double burnrate)
		{
			Material = name;
			Amount = amount;
			Energy = energy;
			BurnRate = burnrate;
		}
		public void Configure(double minimumweight,double efftime)
		{
			MinimumWeight = minimumweight;
			Efficiency = new PT1(efftime, 1, 0);
		}
		void ProcessConversion(double dt)
		{
			double maxoutput = Math.Min(MaterialEfficiency, RequestedPower / MaxPower);
			Efficiency.Set(Math.Min(OutPutSwitch, maxoutput));
			Efficiency.Process(dt);
			Amount -= BurnRate / Energy * (Efficiency.Value * MaxPower) * dt;
		}
		public override void Process(double dt)
		{
			ProcessConversion(dt);
			CurrentEnergyStream.Set(MaxPower * Efficiency.Value);
			CurrentEnergyStream.Process(dt);
		}
	}
	[Flags]
	public enum ConsumerEnergyState
	{
		TurnedOff,
		Standby,
		LowLevel,
		MediumLevel,
		OperatingLevel,
		Overclocked
	}
	public class EnergyConsumer
	{
		public double OperatingPower;
		public double ReceivedPower;
		public ConsumerEnergyState State
		{
			get
			{
				if (ReceivedPower / OperatingPower < 0.02)
					return ConsumerEnergyState.TurnedOff;
				if (ReceivedPower / OperatingPower < 0.20)
					return ConsumerEnergyState.Standby;
				if (ReceivedPower / OperatingPower < 0.50)
					return ConsumerEnergyState.LowLevel;
				if (ReceivedPower / OperatingPower < 0.90)
					return ConsumerEnergyState.MediumLevel;
				if (ReceivedPower / OperatingPower < 1.05)
					return ConsumerEnergyState.OperatingLevel;
				return ConsumerEnergyState.Overclocked;
			}
		}

		void ApplyReceivedPower()
		{
		}
		public virtual void Process(double dt)
		{
		}
		public enum EnergyState
		{
		}
		PT1 EnergyLevel;
		void ReceiveEnergy(double amount)
		{
		}
		void ProcessEnergy(double dt)
		{
		}
	}
	public class EnergySystem
	{
		public List<EnergyProducer> Sources = new List<EnergyProducer>();
		public List<EnergyConsumer> Consumers = new List<EnergyConsumer>();

		public EnergySystem()
		{
		}
		public void Process(double dt)
		{
			double CurrentEnergy = 0;
		}
	}
	[Flags]
	public enum EnergySourceMode
	{
		Solar,
		SpaceEnergy,
		Matterconversion,
		Reacion
	}
	public class EnergySource
	{
		public EnergySourceMode Mode;
		public bool StoreEnergy;

		public EnergySource(EnergySourceMode mode, bool storing)
		{
			Mode = mode;
			//StoreEnergy;
		}
	}
}